package org.spruice;

import org.picocontainer.DefaultPicoContainer;

import java.util.ArrayList;
import java.util.List;

public class ModuleLifecycle {

    private final DefaultPicoContainer cont;
    private final List<Runnable> init = new ArrayList<Runnable>();
    private final List<Runnable> start = new ArrayList<Runnable>();
    private final List<Runnable> stop = new ArrayList<Runnable>();
    private final List<Runnable> destroy = new ArrayList<Runnable>();

    public ModuleLifecycle(DefaultPicoContainer cont) {
        this.cont = cont;
    }

    public void addInit(Runnable r) {
        init.add(r);
    }

    public void addInit(final Object key, final String method) {
        create(init, key, method);
    }

    public void addStart(Object key, String method) {
        create(start, key, method);
    }

    public void addStop(Object key, String method) {
        create(stop, key, method);
    }

    public void addDestroy(Object key, String method) {
        create(destroy, key, method);
    }

    private void create(List<Runnable> list, final Object key, final String method) {
        Runnable initRun = new Runnable() {
            public void run() {
                invoke(cont.getComponent(key), method);
            }
        };
        list.add(initRun);
    }

    private void invoke(Object component, String method) {
        try {
            component.getClass().getMethod(method).invoke(component);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void stop() {
        runAll(stop);
    }

    public void init() {
        runAll(init);
    }

    public void start() {
        runAll(start);
    }

    public void dispose() {
        runAll(destroy);
    }

    private void runAll(List<Runnable> stop) {
        for (Runnable runnable : stop) {
            runnable.run();
        }
    }
}
